package com.example.demo;

import com.example.demo.utils.CheckPwdUtils;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.core.io.ClassPathResource;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class CheckPassword {

    public static final String FILE_NAME="filtered_weak_pass.txt";

    public static final int TIMES=10000;

    public static final String[] WEAK_PASSWORD_ARRAY={
            "123456",
            "Q1W2E3R4",
            "q1w2e3r4",
            "1QAZ2WSX",
            "1qaz2wsx",
            "123456QWERTY",
            "123456qwerty",
            "11111111",
            "123qwe!@#",
            "123qweasd",
            "12681268",
            "192.168.0.1",
            "192.168.1.1",
            "192.168.2.1",
            "777!@#$%",
            "7ujm8ik,",
            "a1b2c3d4",
            "admin1234",
            "admin4488",
            "admin66666"
    };

    public static void main(String[] args) {
        System.out.println("=================== program start !===================");
        long start=System.currentTimeMillis();
        Cache<String , String > cacheCaffeine = Caffeine.newBuilder()
                //初始数量
                .initialCapacity(1)
                //最大条数
                .maximumSize(10)
                //expireAfterWrite和expireAfterAccess同时存在时，以expireAfterWrite为准
                //最后一次写操作后经过指定时间过期
                .expireAfterWrite(60, TimeUnit.SECONDS)
                //最后一次读或写操作后经过指定时间过期
                .expireAfterAccess(60, TimeUnit.SECONDS)
                .softValues()
                .build();
        String key="pwd";
        String dict = cacheCaffeine.get(key, k -> CheckPassword.create(key));
        long checkEnd=System.currentTimeMillis();
        System.out.println("=================== LOAD CACHE cost "+(checkEnd-start)+" ms!===================");
//        for (int i = 0; i < WEAK_PASSWORD_ARRAY.length; i++) {
//            String tmpPwd=WEAK_PASSWORD_ARRAY[i];
//            if (isPasswordWeak(tmpPwd,dict)) {
//                System.out.println(tmpPwd+" is in weak password!");
//            }
//            else {
//                System.out.println(tmpPwd+" is =======STRONG!!!=========!");
//            }
//        }
//
//        long checkEnd=System.currentTimeMillis();
//        System.out.println("=================== checkPwd cost "+(checkEnd-start)+" ms!===================");
//
//        dict = cacheCaffeine.get(key, k -> CheckPassword.create(key));
        int strong=0,weak=0;
        for (int i = 0; i < TIMES; i++) {
            String tmpPwd=generateRandomString(8);
            if (isPasswordWeak(tmpPwd,dict)) {
                System.out.println(tmpPwd+" is =======WEAK!!!=========!");
                weak++;
            }
            else {
//                System.out.println(tmpPwd+" is =======STRONG!!!=========!");
                strong++;
            }
        }
        long checkEnd2=System.currentTimeMillis();
        System.out.println("=================== checkPwd cost "+(checkEnd2-checkEnd)+" ms!===================");
        System.out.println("weak:"+weak+"  strong:"+strong);
    }


    public static String generateRandomString(int length) {
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int index = random.nextInt(characters.length());
            char randomChar = characters.charAt(index);
            sb.append(randomChar);
        }
        return sb.toString();
    }



    public static boolean isPasswordWeak(String password, String dict) {
        if (password != null && password.length() > 0 && !"".equals(password)
                && CheckPwdUtils.EvalPWD(password)) {
            if (dict.indexOf(password) < 0) {
                return false;
            } else {
                System.out.println(password + "不符合弱密码字典要求");
            }
        } else {
            System.out.println(password + "不符合密码要求，4选3和长度要求！");
        }
        return true;
    }

    public static String create(String  key) {
        long start=System.currentTimeMillis();
        String dict=null;
        try {
            dict=getStringFromResourceFile(FILE_NAME);
        } catch (IOException e) {
            e.printStackTrace();
        }
        long loadEnd=System.currentTimeMillis();
        System.out.println("=================== load file end cost "+(loadEnd-start)+" ms!==================="+key);
        return dict;
    }

    public static String getStringFromResourceFile(String path) throws IOException {
//        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(fileName);
        ClassPathResource classPathResource = new ClassPathResource(path);
        InputStream inputStream =classPathResource.getInputStream();
        BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder=new StringBuilder();
        String line=null;
        while ((line = bufferedReader.readLine()) != null) {
            // 拼接换行符
            stringBuilder.append(line + "\n");
        }
        inputStream.close();
        bufferedReader.close();
        return stringBuilder.toString();
    }

}
